package com.wangzhe.builder;

import com.wangzhe.bean.Constants;
import com.wangzhe.bean.FieldInfo;
import com.wangzhe.bean.TableInfo;
import com.wangzhe.utils.DateTimeUtil;
import com.wangzhe.utils.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

/**
 * @author 王哲
 * @ClassName BuilderPojo
 * @create 2023--六月--下午4:38
 * @Description 构造实体类
 * @Version V1.0
 */
public class BuilderPojo {

    private static Logger logger = LoggerFactory.getLogger(BuilderPojo.class);

    public static void builderPojo(TableInfo tableInfo) {
        File folder = new File(Constants.POJO_PATH);
        if (!folder.exists()) {
            folder.mkdirs();
        }

        File file = new File(folder, tableInfo.getBeanName() + ".java");

        OutputStream os = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            os = new FileOutputStream(file);
            osw = new OutputStreamWriter(os, "utf-8");
            bw = new BufferedWriter(osw);

            bw.write("package " + Constants.POJO_BASE + "; ");
            bw.newLine();
            bw.newLine();

            bw.write("import java.io.Serializable;");
            bw.newLine();

            bw.write("import lombok.AllArgsConstructor;");
            bw.newLine();
            bw.write("import lombok.Data;");
            bw.newLine();
            bw.write("import lombok.NoArgsConstructor;");
            bw.newLine();
            bw.write("import lombok.ToString;");
            bw.newLine();


            if (tableInfo.isHaveBigDecimal()) {
                bw.write("import java.math.BigDecimal;");
                bw.newLine();
            }
            if (tableInfo.isHaveDate() || tableInfo.isHaveDateTime()) {
                bw.write("import java.util.Date;");
                bw.newLine();

                bw.write(Constants.DB_DATE_FORMAT_IMPORT);
                bw.newLine();
                bw.write(Constants.DB_DATE_PARSE_IMPORT);
                bw.newLine();
            }

            for (FieldInfo fieldInfo : tableInfo.getFieldInfo()) {
                if (ArrayUtils.contains(Constants.DB_IGNORE_BEAN_FIELD, fieldInfo.getPropertyName())) {
                    bw.write(Constants.DB_IGNORE_BEAN_IMPORT);
                    bw.newLine();
                    break;
                }
            }
            bw.newLine();
            bw.newLine();
            BuilderComment.createClassComment(bw, tableInfo.getTableName() + "表的实体类");

            bw.write("@Data");
            bw.newLine();
            bw.write("@AllArgsConstructor");
            bw.newLine();
            bw.write("@NoArgsConstructor");
            bw.newLine();
            bw.write("@ToString");
            bw.newLine();
            bw.write("public class " + tableInfo.getBeanName() + " implements Serializable {");
            bw.newLine();
            bw.newLine();

            //拿到所以属性
            for (FieldInfo fieldInfo : tableInfo.getFieldInfo()) {
                BuilderComment.createFieldComment(bw, fieldInfo.getComment());

                //添加注解
                if (ArrayUtils.contains(Constants.SQL_DATE_TYPES, fieldInfo.getSqlType())) {
                    bw.write("\t" + String.format(Constants.DB_DATE_FORMAT_EXPRESSION,DateTimeUtil.DATE_FORMAT_YYYY_MM_DD));
                    bw.newLine();
                    bw.write("\t" + String.format(Constants.DB_DATE_PARSE_EXPRESSION,DateTimeUtil.DATE_FORMAT_YYYY_MM_DD));
                    bw.newLine();
                }

                if (ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES, fieldInfo.getSqlType())) {
                    bw.write("\t" + String.format(Constants.DB_DATE_FORMAT_EXPRESSION,DateTimeUtil.DATE_FORMAT_YYYY_MM_DD_HH_MM_SS));
                    bw.newLine();
                    bw.write("\t" + String.format(Constants.DB_DATE_PARSE_EXPRESSION,DateTimeUtil.DATE_FORMAT_YYYY_MM_DD_HH_MM_SS));
                    bw.newLine();
                }

                //排除字段
                if (ArrayUtils.contains(Constants.DB_IGNORE_BEAN_FIELD, fieldInfo.getPropertyName())) {
                    bw.write("\t" +Constants.DB_IGNORE_BEAN_EXPRESSION);
                    bw.newLine();
                }

                bw.write("\tprivate " + fieldInfo.getFieldJavaType() + " " + fieldInfo.getPropertyName() + ";");
                bw.newLine();
                bw.newLine();
            }

            //提供get方法
            for (FieldInfo fieldInfo : tableInfo.getFieldInfo()) {
                BuilderComment.createMethodComment(bw, "提供" + fieldInfo.getComment() + "的get方法");
                bw.write("\tpublic " + fieldInfo.getFieldJavaType() + " get" + StringUtils.upperCaseFirst(fieldInfo.getPropertyName()) + "(){");
                bw.newLine();
                bw.write("\t\treturn this." + fieldInfo.getPropertyName() + ";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
            }

            //提供set方法
            for (FieldInfo fieldInfo : tableInfo.getFieldInfo()) {
                BuilderComment.createMethodComment(bw, "提供" + fieldInfo.getComment() + "的set方法");
                bw.write("\tpublic void set" + StringUtils.upperCaseFirst(fieldInfo.getPropertyName()) + "(" + fieldInfo.getFieldJavaType() + " " + fieldInfo.getPropertyName() + "){");
                bw.newLine();
                bw.write("\t\tthis." + fieldInfo.getPropertyName() + "=" + fieldInfo.getPropertyName() + ";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
            }

            bw.newLine();
            bw.write("}");
            bw.flush();
        } catch (Exception e) {
            logger.info("创建pojo失败:{}", e.getMessage());
        } finally {
            try {
                if (bw != null) {
                    bw.close();
                }
                if (osw != null) {
                    osw.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
